import fs from 'fs'
import pLimit from 'p-limit'
import path from 'path'
import cliProgress from 'cli-progress'
// 引入封装
import { axiosInstance as axios, fileUtils } from './axios.js'

main()

// ===================== 主函数 =====================
export async function main() {
  const { keywordsToProcess } = fileUtils.resumeCrawling()

  try {
    for (const keyword of keywordsToProcess) {
      let reachedEnd = false
      let page = 1

      while (!reachedEnd) {
        const res = await searchKeyword(keyword, page)
        if (res.imgs.length) {
          console.log(`✨ 正在下载第 ${page} 页的图片（总共 ${res.total_pages} 页 ${res.total} 张图片）`)
          await downloadImgs(keyword, res.imgs)
          page++
        }

        if (res.total_pages <= page) {
          console.log(`✅ ${keyword}的图片下载完成！\n`)
          reachedEnd = true
        }
      }

      // 更新状态文件
      fileUtils.writeConfig({ lastProcessedKeyword: keyword })
    }
  } catch (error) {
    fileUtils.logError(error)
  }
}

// ===================== 搜索图片接口 =====================
async function searchKeyword(keyword: string, page: number = 1) {
  const res = await axios<{
    total: number
    total_pages: number
    results: {
      id: string
      urls: { raw: string }
      premium: boolean
    }[]
  }>({
    url: 'https://unsplash.com/napi/search/photos', // 未登入 api
    // url: 'https://api.unsplash.com/search/photos',  // 登入的 api
    method: 'GET',
    params: {
      page: page,
      per_page: 20,
      query: keyword,
      // client_id: 'CoEW3leUjb0GDoLNCm7uof667E65x--RauD0TJj49TU',
    },
  })

  // 过滤一下，只保留非付费图片
  const imgs = res.data.results
    .filter((result) => !result.premium)
    .map((result) => ({
      id: result.id,
      url: result.urls.raw,
    }))

  return {
    total: res.data.total,
    total_pages: res.data.total_pages,
    imgs: imgs,
  }
}

// ===================== 下载图片到本地 =====================
async function downloadImg(imgUrl: string, filePath: string) {
  // 如果文件已经存在，则直接返回
  if (fs.existsSync(filePath)) {
    return
  }
  const res = await axios
    .get(imgUrl, {
      responseType: 'arraybuffer',
    })
    .catch((error) => {
      throw new Error(`⚠️ 下载图片失败：${imgUrl}`, { cause: error })
    })

  fs.writeFileSync(filePath, Buffer.from(res.data))
}

async function downloadImgs(keyword: string, imgs: { id: string; url: string }[]) {
  const dir = path.resolve(fileUtils.outDirPath, keyword)
  fs.mkdirSync(dir, { recursive: true }) //确保目录存在
  const limit = pLimit(fileUtils.config.concurrency) // 限制下载并发

  // 初始化进度条
  const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.rect)
  progressBar.start(imgs.length, 0)

  const promises = imgs.map(async (img, index) => {
    const fileName = img.id + '.jpg'

    return limit(async () => {
      const filePath = `${dir}/${fileName}`
      await downloadImg(img.url, filePath)
      progressBar.increment() // 更新进度条
    })
  })

  await Promise.all(promises)
  progressBar.stop() // 停止进度条
}
